import os
import re
import openpyxl
from itertools import groupby


def remote_duplicate(data):
    if not isinstance(data, list):
        return data
    data.sort()
    data_list = [key for key, _ in groupby(data)]
    if len(data_list) == 1:
        return data_list[0]
    if len(data_list) == 0:
        return ""
    return data_list


def parse_nginx_log(log_path):
    max_core_file_size_regex = r'^Max core file size\s*(?P<max_core_file_size>[0-9a-z ]*)'
    max_processes_regex = r'^Max processes\s*(?P<max_processes>[0-9a-z ]*)'
    max_open_files_regex = r'^Max open files\s*(?P<max_open_files>[0-9a-z ]*)'
    tcp_max_syn_backlog_regex = r'^net.ipv4.tcp_max_syn_backlog = (?P<tcp_max_syn_backlog>[0-9]*)'
    tcp_syncookies_regex = r'^net.ipv4.tcp_syncookies = (?P<tcp_syncookies>[0-9]*)'
    tcp_synack_retries_regex = r'^net.ipv4.tcp_synack_retries = (?P<tcp_synack_retries>[0-9]*)'
    tcp_timestamps_regex = r'^net.ipv4.tcp_timestamps = (?P<tcp_timestamps>[0-9]*)'
    tcp_tw_reuse_regex = r'^net.ipv4.tcp_tw_reuse = (?P<tcp_tw_reuse>[0-9]*)'
    somaxconn_regex = r'^net.core.somaxconn = (?P<somaxconn>[0-9]*)'
    ssl_regex = r'^\s*listen\s+.*(?P<ssl>ssl).*'
    gzip_regex = r'^\s*gzip\s+.*(?P<gzip>on).*'
    openssl_regex = r'^built with OpenSSL (?P<openssl>[0-9.]*[a-z]?).*'
    cpu_info_regex = r'^CPU\(s\)\:\s+(?P<cpu_cores>\d+)$'
    cpu_usage_idle_regex = r'^%Cpu\(s\):.*ni, (?P<cpu_usage_idle>[0-9.]*) id,.*$'
    user_regex = r'^\s*user\s*(?P<nginx_user>.*);.*$'
    run_user_regex=r'^nginx运行用户:(?P<run_user>[a-zA-Z0-9-]*),.*$'
    nginx_version_regex = r'^nginx version: (?P<nginx_version>[a-zA-Z/]*[0-9.]+)$'
    configure_arguments_regex = r'^configure arguments: --(?P<nginx_modules>.*)$'
    max_open_file_regex = r'^Max open files \W*(?P<max_open_file>[0-9]+).*$'
    worker_processes_regex = r'^\s*worker_processes\s*(?P<worker_processes>[0-9]*|auto);.*$'
    worker_connections_regex = r'^\s*worker_connections\s*(?P<worker_connections>\d+);.*$'
    worker_rlimit_nofile_regex = r'^\s*worker_rlimit_nofile\s*(?P<worker_rlimit_nofile>\d+);.*$'
    keepalive_timeout_regex = r'^\s*keepalive_timeout\s*(?P<keepalive_timeout>[0-9s]+);.*'
    client_max_body_size_regex = r'\s*client_max_body_size\s+(?P<client_max_body_size>\d+[a-zA-Z]);.*'
    server_tokens_regex = r'\s*server_tokens\s+(?P<server_tokens>\w+);.*'
    autoindex_regex = r'\s*autoindex\s+(?P<autoindex>\w+);.*'
    proxy_buffering_regex = r'\s*proxy_buffering\s+(?P<proxy_buffering>\w+);.*'
    proxy_buffer_size_regex = r'\s*proxy_buffer_size\s+(?P<proxy_buffer_size>[0-9]+[0-9km ]+);.*'
    proxy_buffers_regex = r'\s*proxy_buffers\s+(?P<proxy_buffers>[0-9]+[0-9km ]+);.*'
    proxy_busy_buffers_size_regex = r'\s*proxy_busy_buffers_size\s+(?P<proxy_busy_buffers_size>[0-9]+[0-9km ]+);.*'
    memory_regex = r'^Mem:\W+(?P<memory_size>[0-9]+)\W+(?P<memory_used>[0-9]+)\W+(?P<memory_free>[0-9]+)\W+(?P<memory_shared>[0-9]+)\W+(?P<memory_buff_cache>[0-9]+).*$'
    with_pcre_regex = r'^.* --with-pcre=(?P<with_pcre>.*?) .*$'
    with_zlib_regex = r'^.* --with-zlib=(?P<with_zlib>.*?) .*$'
    # nginx_module_vts_regx = r'^.* --add-module=.*/(?P<nginx_module_vts>nginx-module-vts-.*?) .*$'
    http_realip_module_regex = r'^.* --(?P<http_realip_module>with-http_realip_module) .*$'
    http_ssl_module_regex = r'^.* --(?P<http_ssl_module>with-http_ssl_module) .*$'
    http_v2_module_regex = r'^.* --(?P<http_v2_module>with-http_v2_module) .*$'
    test_regex = r'^.* --(?P<test>with-test) .*$'
    pcre_version_regex = r'^pcre版本收集: (?P<pcre_version>[0-9.]*)$'
    pcre_devel_version_regex = r'^pcre-devel版本收集: pcre-devel-(?P<pcre_devel_version>[0-9.]*)-.*$'
    zlib_devel_version_regex = r'^zlib-devel版本收集: zlib-devel-(?P<zlib_devel_version>[0-9.]*)-.*$'
    with open(log_path, 'r', encoding='utf-8', errors='ignore') as f:
        openssl_list = []
        cpu_cores_list = []
        ssl_list = []
        gzip_list = []
        nginx_version_list = []
        nginx_modules_list = []
        max_open_file_list = []
        worker_processes_list = []
        worker_connections_list = []
        worker_rlimit_nofile_list = []
        keepalive_timeout_list = []
        client_max_body_size_list = []
        server_tokens_list = []
        autoindex_list = []
        memory_list = []
        memory_usage_list = []
        proxy_buffering_list = []
        proxy_buffer_size_list = []
        proxy_buffers_list = []
        proxy_busy_buffers_size_list = []
        nginx_user_list = []
        cpu_usage_idle_list = []
        with_pcre = ""
        with_zlib = ""
        http_realip_module = ""
        http_ssl_module = ""
        http_v2_module = ""
        test = ""
        pcre_version_list = []
        zlib_devel_version_list = []
        pcre_devel_version_list = []
        run_user_list = []
        tcp_max_syn_backlog_list = []
        tcp_syncookies_list = []
        tcp_synack_retries_list = []
        tcp_timestamps_list = []
        tcp_tw_reuse_list = []
        somaxconn_list = []
        max_core_file_size_list = []
        max_processes_list = []
        max_open_files_list = []
        for line in f:
            line = line.strip()
            if line:
                ssl = re.match(ssl_regex, line)
                gzip = re.match(gzip_regex, line)
                openssl = re.match(openssl_regex, line)
                cpu_cores = re.match(cpu_info_regex, line)
                cpu_usage_idle = re.match(cpu_usage_idle_regex, line)
                nginx_user = re.match(user_regex, line)
                run_user = re.match(run_user_regex, line)
                nginx_version = re.match(nginx_version_regex, line)
                nginx_modules = re.match(configure_arguments_regex, line)
                max_open_file = re.match(max_open_file_regex, line)
                worker_processes = re.match(worker_processes_regex, line)
                worker_connections = re.match(worker_connections_regex, line)
                worker_rlimit_nofile = re.match(worker_rlimit_nofile_regex, line)
                keepalive_timeout = re.match(keepalive_timeout_regex, line)
                client_max_body_size = re.match(client_max_body_size_regex, line)
                server_tokens = re.match(server_tokens_regex, line)
                autoindex = re.match(autoindex_regex, line)
                memory = re.match(memory_regex, line)
                proxy_buffering = re.match(proxy_buffering_regex, line)
                proxy_buffer_size = re.match(proxy_buffer_size_regex, line)
                proxy_buffers = re.match(proxy_buffers_regex, line)
                proxy_busy_buffers_size = re.match(proxy_busy_buffers_size_regex, line)
                pcre_version = re.match(pcre_version_regex, line)
                pcre_devel_version = re.match(pcre_devel_version_regex, line)
                zlib_devel_version = re.match(zlib_devel_version_regex, line)
                tcp_max_syn_backlog = re.match(tcp_max_syn_backlog_regex, line)
                tcp_syncookies = re.match(tcp_syncookies_regex, line)
                tcp_synack_retries = re.match(tcp_synack_retries_regex, line)
                tcp_timestamps = re.match(tcp_timestamps_regex, line)
                tcp_tw_reuse = re.match(tcp_tw_reuse_regex, line)
                somaxconn = re.match(somaxconn_regex, line)
                max_core_file_size = re.match(max_core_file_size_regex, line)
                max_processes = re.match(max_processes_regex, line)
                max_open_files = re.match(max_open_files_regex, line)
                if tcp_max_syn_backlog:
                    tcp_max_syn_backlog_list.append(tcp_max_syn_backlog.group('tcp_max_syn_backlog'))
                if tcp_syncookies:
                    tcp_syncookies_list.append(tcp_syncookies.group('tcp_syncookies'))
                if tcp_synack_retries:
                    tcp_synack_retries_list.append(tcp_synack_retries.group('tcp_synack_retries'))
                if tcp_timestamps:
                    tcp_timestamps_list.append(tcp_timestamps.group('tcp_timestamps'))
                if tcp_tw_reuse:
                    tcp_tw_reuse_list.append(tcp_tw_reuse.group('tcp_tw_reuse'))
                if somaxconn:
                    somaxconn_list.append(somaxconn.group('somaxconn'))
                if max_core_file_size:
                    max_core_file_size_list.append(max_core_file_size.group('max_core_file_size'))
                if max_processes:
                    max_processes_list.append(max_processes.group('max_processes'))
                if max_open_files:
                    max_open_files_list.append(max_open_files.group('max_open_files'))
                if gzip:
                    gzip_list.append(gzip.group('gzip'))
                if ssl:
                    ssl_list.append(ssl.group('ssl'))
                if openssl:
                    openssl_list.append(openssl.group('openssl'))
                if cpu_usage_idle:
                    cpu_usage_idle_list.append(cpu_usage_idle.groups('cpu_usage'))
                if nginx_user:
                    nginx_user_list.append(nginx_user.group('nginx_user'))
                if run_user:
                    run_user_list.append(run_user.group('run_user'))
                if proxy_buffering:
                    proxy_buffering_list.append(proxy_buffering.group('proxy_buffering'))
                if proxy_buffer_size:
                    proxy_buffer_size_list.append(proxy_buffer_size.group('proxy_buffer_size'))
                if proxy_buffers:
                    proxy_buffers_list.append(proxy_buffers.group('proxy_buffers'))
                if proxy_busy_buffers_size:
                    proxy_busy_buffers_size_list.append(proxy_busy_buffers_size.group('proxy_busy_buffers_size'))
                if cpu_cores:
                    # print("cpu_cores", cpu_cores.group('cpu_cores'))
                    cpu_cores_list.append(cpu_cores.group('cpu_cores'))
                if nginx_version:
                    # print("nginx_version", nginx_version.group('nginx_version'))
                    nginx_version_list.append(nginx_version.group('nginx_version'))
                if nginx_modules:
                    nginx_modules_list.append(nginx_modules.group('nginx_modules'))
                    if len(nginx_modules_list) > 0:
                        for nginx_module_data in nginx_modules_list:
                            if re.search(with_pcre_regex, nginx_module_data) is not None:
                                with_pcre = re.search(with_pcre_regex, nginx_module_data).group("with_pcre")

                            if re.search(with_zlib_regex, nginx_module_data) is not None:
                                with_zlib = re.search(with_zlib_regex, nginx_module_data).group("with_zlib")

                            if re.search(http_realip_module_regex, nginx_module_data) is not None:
                                http_realip_module = re.search(http_realip_module_regex, nginx_module_data).group(
                                    "http_realip_module")

                            if re.search(http_ssl_module_regex, nginx_module_data) is not None:
                                http_ssl_module = re.search(http_ssl_module_regex, nginx_module_data).group(
                                    "http_ssl_module")

                            if re.search(http_v2_module_regex, nginx_module_data) is not None:
                                http_v2_module = re.search(http_v2_module_regex, nginx_module_data).group(
                                    "http_v2_module")

                            if re.search(test_regex, nginx_module_data) is not None:
                                test = re.search(test_regex, nginx_module_data).group("test")
                if max_open_file:
                    # print("max_open_file", max_open_file.group('max_open_file'))
                    max_open_file_list.append(max_open_file.group('max_open_file'))
                if worker_processes:
                    # print("worker_processes", worker_processes.group('worker_processes'))
                    worker_processes_list.append(worker_processes.group('worker_processes'))
                if worker_connections:
                    # print("worker_connections", worker_connections.group('worker_connections'))
                    worker_connections_list.append(worker_connections.group('worker_connections'))
                if worker_rlimit_nofile:
                    worker_rlimit_nofile_list.append(worker_rlimit_nofile.group('worker_rlimit_nofile'))
                if keepalive_timeout:
                    # print("keepalive_timeout", keepalive_timeout.group('keepalive_timeout'))
                    keepalive_timeout_list.append(keepalive_timeout.group('keepalive_timeout'))
                if client_max_body_size:
                    # print('client_max_body_size', client_max_body_size.group('client_max_body_size'))
                    client_max_body_size_list.append(client_max_body_size.group('client_max_body_size'))
                if server_tokens:
                    # print('server_tokens', server_tokens.group('server_tokens'))
                    server_tokens_list.append(server_tokens.group('server_tokens'))
                if autoindex:
                    # print('autoindex', autoindex.group('autoindex'))
                    autoindex_list.append(autoindex.group('autoindex'))
                if memory:
                    # print('memory_size', memory.group('memory_size'))
                    memory_list.append(memory.group('memory_size'))
                    memory_usage_list.append(int(memory.group('memory_used')) / int(memory.group('memory_size')))
                if pcre_version:
                    pcre_version_list.append(pcre_version.group('pcre_version'))
                if pcre_devel_version:
                    pcre_devel_version_list.append(pcre_devel_version.group('pcre_devel_version'))
                if zlib_devel_version:
                    zlib_devel_version_list.append(zlib_devel_version.group('zlib_devel_version'))
    return {
        'ssl': remote_duplicate(ssl_list),
        'gzip': remote_duplicate(gzip_list),
        'openssl': remote_duplicate(openssl_list),
        'cpu_cores': remote_duplicate(cpu_cores_list),
        'cpu_usage_idle': remote_duplicate(cpu_usage_idle_list),
        'nginx_user': remote_duplicate(nginx_user_list),
        'run_user': remote_duplicate(run_user_list),
        'nginx_version': remote_duplicate(nginx_version_list),
        'nginx_modules': remote_duplicate(nginx_modules_list),
        'with_pcre': remote_duplicate(with_pcre),
        "with_zlib": remote_duplicate(with_zlib),
        'max_open_file': remote_duplicate(max_open_file_list),
        'worker_processes': remote_duplicate(worker_processes_list),
        'worker_connections': remote_duplicate(worker_connections_list),
        'worker_rlimit_nofile': remote_duplicate(worker_rlimit_nofile_list),
        'keepalive_timeout': remote_duplicate(keepalive_timeout_list),
        'client_max_body_size': remote_duplicate(client_max_body_size_list),
        'server_tokens': remote_duplicate(server_tokens_list),
        'autoindex': remote_duplicate(autoindex_list),
        "proxy_buffering": remote_duplicate(proxy_buffering_list),
        "proxy_buffer_size": remote_duplicate(proxy_buffer_size_list),
        "proxy_buffers": remote_duplicate(proxy_buffers_list),
        "proxy_busy_buffers_size": remote_duplicate(proxy_busy_buffers_size_list),
        'memory_size': remote_duplicate(memory_list),
        'memory_usage': remote_duplicate(memory_usage_list),
        'http_realip_module': remote_duplicate(http_realip_module),
        'http_ssl_module': remote_duplicate(http_ssl_module),
        'http_v2_module': remote_duplicate(http_v2_module),
        'pcre_version': remote_duplicate(pcre_version_list),
        'pcre_devel_version': remote_duplicate(pcre_devel_version_list),
        'zlib_devel_version': remote_duplicate(zlib_devel_version_list),
        'tcp_max_syn_backlog': remote_duplicate(tcp_max_syn_backlog_list),
        'tcp_syncookies': remote_duplicate(tcp_syncookies_list),
        'tcp_synack_retries': remote_duplicate(tcp_synack_retries_list),
        'tcp_timestamps': remote_duplicate(tcp_timestamps_list),
        'tcp_tw_reuse': remote_duplicate(tcp_tw_reuse_list),
        'somaxconn': remote_duplicate(somaxconn_list),
        'max_core_file_size': remote_duplicate(max_core_file_size_list),
        'max_processes': remote_duplicate(max_processes_list),
        'max_open_files': remote_duplicate(max_open_files_list)

    }


def nginx_log_collector(log_path):
    projects = os.listdir(log_path)
    project_dict = {}
    for project in projects:
        project_list = []
        project_dir = os.path.join(log_path, project)
        project_logs = os.listdir(project_dir)
        for project_log in project_logs:
            if 'nginx' in project_log:
                project_log_path = os.path.join(project_dir, project_log)
                project_list.append(project_log_path)
        project_dict[project] = project_list
    return project_dict


if __name__ == '__main__':
    default_path = 'C:\\Users\\lixiu\\Downloads\\一季度巡检结果0430'
    nginx_dict = nginx_log_collector(default_path)
    # print(nginx_dict)
    excel_filename = 'test.xlsx'
    sheet_name = 'Sheet1'
    wb = openpyxl.Workbook()
    ws = wb.active
    row_index = 0
    column_index = 0
    j = 0

    title_data = ['openssl', 'ssl', 'gzip', 'log_file', 'project', 'cpu_cores', 'cpu_usage_idle', 'nginx_user', 'run_user',
                  'memory_size', 'memory_usage', 'nginx_version', 'max_open_file', 'worker_rlimit_nofile',
                  'worker_processes', 'worker_connections', 'keepalive_timeout', 'client_max_body_size',
                  'server_tokens', 'autoindex', 'nginx_modules', "with_pcre", "with_zlib", "proxy_buffering",
                  "proxy_buffer_size",
                  "proxy_buffers", "proxy_busy_buffers_size", "http_realip_module", "http_ssl_module", 'http_v2_module',
                  "pcre_version", "pcre_devel_version", "zlib_devel_version","tcp_max_syn_backlog","tcp_syncookies","tcp_synack_retries","tcp_timestamps","tcp_tw_reuse","somaxconn",
                  'max_core_file_size', 'max_processes', 'max_open_files'
                  ]
    row_index += 1
    for data in title_data:
        j += 1
        ws.cell(row=row_index, column=j).value = data
    for project in nginx_dict:
        if len(nginx_dict[project]) > 0:
            for project_log_file in nginx_dict[project]:
                data_dict = parse_nginx_log(project_log_file)
                data_dict['log_file'] = project_log_file.split('\\')[-1]
                data_dict['project'] = project

                row_index += 1
                j = 0
                for data in title_data:
                    j += 1
                    ws.cell(row=row_index, column=j).value = str(data_dict[data])
    wb.save(excel_filename)
